﻿#include "unrealircd.h"

/**
 * 使用秒嘀科技的接口来实现发送短信
 * 
 */

typedef struct PhoneSMS PhoneSMS;

CMD_FUNC(cmd_phoneVerification);
void SendRegistSMS(Client *client ,char * phoneNumber,int sendType);
char **get_sms_head();
HTTPREQUESTSUCCESSCALLBACK(sendSmsSuccessCallfunc);
HTTPREQUESTFAILCALLBACK(sendSmsfaileCallfunc);

struct PhoneSMS{
	char *phone;
	char *code;
	int sendType;
};
IMConfigureSave send_Phone_sms_configure_save;

ModuleHeader MOD_HEADER
= {
	"third/miaodiPhoneSMS",
	"1.1",
	"This module will send phone message ",
	"waitch",
	"unrealircd-5",
};

MOD_TEST(){
    MARK_AS_OFFICIAL_MODULE(modinfo);
	EfunctionAddVoid(modinfo->handle, EFUNC_PHONE_SMS, SendRegistSMS);
	return MOD_SUCCESS;
}

MOD_INIT()
{
	send_Phone_sms_configure_save.configure_name=NULL;
	send_Phone_sms_configure_save.configure_value=NULL;
	send_Phone_sms_configure_save.next=NULL;
	return MOD_SUCCESS;
}

MOD_LOAD()
{
	return MOD_SUCCESS;
}

MOD_UNLOAD()
{
	return MOD_SUCCESS;
}



/**
 * 发送注册手机验证码
 * @param[in] phoneNumber:手机号
 */
void SendRegistSMS(Client *client ,char * phoneNumber,int sendType){
	
	IMConfigureSave *template_id=D_FindImConfigureSaveNode(&send_Phone_sms_configure_save,"MIAODI_SMS_TEMPLATE_ID");
	if(!template_id){
		sendnumeric(client, CONFIGUREFAILEBYLACKMESSAGE, "PHONEVERIFICATION","MIAODI_SMS_TEMPLATE_ID");
		return;
	}
	IMConfigureSave *account_sid=D_FindImConfigureSaveNode(&send_Phone_sms_configure_save,"MIAODI_SMS_ACCOUNT_SID");
	if(!account_sid){
		sendnumeric(client, CONFIGUREFAILEBYLACKMESSAGE, "PHONEVERIFICATION","MIAODI_SMS_ACCOUNT_SID");
		return;
	}
	IMConfigureSave *auth_token=D_FindImConfigureSaveNode(&send_Phone_sms_configure_save,"MIAODI_SMS_AUTH_TOKEN");
	if(!auth_token){
		sendnumeric(client, CONFIGUREFAILEBYLACKMESSAGE, "PHONEVERIFICATION","MIAODI_SMS_AUTH_TOKEN");
		return;
	}

	char *param=random_digist(6);
	char *timestamp=getCurrectTimeStamp();
	char temp_sig[100];
	char sig[100];
	sprintf(temp_sig,"%s%s%s",
		account_sid->configure_value,
		auth_token->configure_value,
		timestamp
	);
	md5hash(sig,temp_sig,strlen(temp_sig));
	char data[400];
	sprintf(data,"accountSid=%s&to=%s&templateid=%s&param=%s&timestamp=%s&sig=%s",
			account_sid->configure_value,
			phoneNumber,
			template_id->configure_value,
			param,
			timestamp,
			sig
	);

	ircd_log(LOG_ERROR,"sendSMS,data:%s",data);
	HttpRequestData * requestdata = malloc(sizeof(HttpRequestData));
	char *url="https://openapi.miaodiyun.com/distributor/sendSMS";

	requestdata->url = _strdup(url);
	requestdata->data = _strdup(data);
	PhoneSMS *sms_data=safe_alloc(sizeof(PhoneSMS));
	safe_strdup(sms_data->phone,phoneNumber);
	safe_strdup(sms_data->code,param);
	sms_data->sendType=sendType;
	requestdata->userPoint = sms_data;
    requestdata->client=client;
	requestdata->requestType = 1;
	requestdata->head = get_sms_head(&(requestdata->head_num));
	requestdata->successfinishCallFun = sendSmsSuccessCallfunc;
	requestdata->failefinishCallFun = sendSmsfaileCallfunc;
	add_httpRequestReady(requestdata);

}

char **get_sms_head(int *head_num){
	*head_num = 1;
	char **head = malloc((*head_num) * sizeof(char *));
	head[0] = _strdup("Content-type:application/x-www-form-urlencoded");
	return head;
}

HTTPREQUESTSUCCESSCALLBACK(sendSmsSuccessCallfunc){
	PhoneSMS *user_data=(PhoneSMS *)data;
	cJSON *root,*C_respCode;
	char *error_message=NULL,*respCode;
	root = cJSON_Parse(requestData->response);
	ircd_log(LOG_ERROR,"sendSmsSuccessCallfunc,response:%s",cJSON_Print(root));
	switch (httpCode)
	{
	case 200://是否成功发送
		C_respCode=cJSON_GetObjectItem(root, "respCode");
		if(!C_respCode){
			sendSmsfaileCallfunc(requestData,client,data);
			break;
		}
		respCode= C_respCode->valuestring;

		cJSON *failList=cJSON_GetObjectItem(root,"failList");
		if(failList){
			int faileListSize=cJSON_GetArraySize(failList);
			if(faileListSize>0){
				for(int i=0;i<faileListSize;i++){
					cJSON *faileItem=cJSON_GetArrayItem(failList,i);
					if(faileItem){
						cJSON *C_phone=cJSON_GetObjectItem(faileItem, "phone");
						cJSON *C_itemRespCode=cJSON_GetObjectItem(faileItem, "respCode");
						if(C_phone&&C_itemRespCode){
							char *phone = C_phone->valuestring;
							char *itemRespCode = C_itemRespCode->valuestring;
							ircd_log(LOG_ERROR,"faileList phone:%s,respCode:%s",phone,itemRespCode);
						}
					}
				}
				sendSmsfaileCallfunc(requestData,client,data);
				break;
			}
		}
		

		if(strcmp(respCode,"0000")){
			ircd_log(LOG_ERROR,"faileList phone:%s,respCode:%s",user_data->phone,respCode);
			sendSmsfaileCallfunc(requestData,client,data);
			break;
		}
		//将数据存储到数据库中
		D_im_sms *sms_data=safe_alloc(sizeof(D_im_sms));
		sms_data->code=NULL;
		safe_strdup(sms_data->code,user_data->code);
		sms_data->contactvalue=NULL;
		safe_strdup(sms_data->contactvalue,user_data->phone);
		sms_data->sms_channel=safe_alloc(sizeof(int));
		*(sms_data->sms_channel)=SMS_MODE_PHONE;
		sms_data->sms_type=safe_alloc(sizeof(int));
		*(sms_data->sms_type)=user_data->sendType;
		sms_data->used=safe_alloc(sizeof(int));
		*(sms_data->used)=0;
		sms_data->valid_time=safe_alloc(sizeof(D_TimeStamp));
		D_getCurrectTime(sms_data->valid_time);
		int insertStatus=0;
		char insert_error_message[200]="";
		insertImSms(sms_data,&insertStatus,insert_error_message);
		if(insertStatus==-1){
			ircd_log(LOG_ERROR, "insert im_sms error:%s", insert_error_message);
			sendSmsfaileCallfunc(requestData,client,data);
			break;
		}
		sendnumeric(client, SMSSENDSUCCESS, user_data->phone);
		break;
	default://创建失败
		{
			
			cJSON *response_json = cJSON_GetObjectItem(root, "respDesc");
			if(!response_json){
				safe_strdup(error_message,"unknown error message");
			}
			else if(response_json->valuestring){
				error_message=response_json->valuestring;
			}
			else{
				error_message=cJSON_PrintUnformatted(response_json);
			}
			ircd_log(LOG_ERROR, "sendSMS is error and error %s", error_message);
			sendSmsfaileCallfunc(requestData,client,data);
			break;
		}
	}

	cJSON_Delete(root);
}

HTTPREQUESTFAILCALLBACK(sendSmsfaileCallfunc){
	PhoneSMS *user_data=(PhoneSMS *)data;
	sendnumeric(client, SMSSENDFAILE, user_data->phone);
}